/*----------------------------------------------------------------------------------------
*
*  Copyright 2019, Gao Hai Hui, <fromzeropoint@126.com>.  All rights reserved.
*  https://gitee.com/helloworldghh/xoskit.git
*  Use of this source code is governed by a MIT license
*  that can be found in the License file.
*
----------------------------------------------------------------------------------------*/
#include "../import/head.h"
#include "../data_struct/head.h"
#include "odbc_field.h"
#include "odbc_stmt.h"
#include "mgr.h"

namespace xos_odbc
{

    //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    // 

    static odbc_field::ITEM_DATA xos_item_data;

    //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    // 

    odbc_field::odbc_field()
    {
        init_data();
    }

    odbc_field::~odbc_field()
    {
    }

    //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    // public method

    int odbc_field::get_xos_item_data( ITEM_DATA *& item_ptr )
    {
        int ret = 0;
        xos_item_data.set_container( mgr::container() );
        item_ptr = &xos_item_data;
        return ret;
    }

    //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    // public method

    int odbc_field::set_type( i_stmt::enumValueType eType, int nSize, int nDigitNum )
    {
        int ret = 0;

        xos_stl::release_interface( m_pOwnerStringA );
        xos_stl::release_interface( m_pStringW );
        xos_stl::release_interface( m_pBuf );
        m_pStringA = 0;
        m_nDigitnum = nDigitNum;
        m_eType = eType;

        switch( eType )
        {
        case i_stmt::VT_CHAR_ARRAY:
            {
                m_pBuf = mgr::container()->box()->buf();
                wchar_ptr = (wchar_t *)m_pBuf->get_data( 0, 0, 0, 0 );
                m_nBufSize = m_pBuf->get_buf_size( 0 );
                m_pOwnerStringA = mgr::container()->box()->string();
                m_pStringW = mgr::container()->box()->wstring();
                m_pStringA = m_pOwnerStringA;
            }
            break;
        case i_stmt::VT_DOUBLE:
            {
                double_ptr = &double_v;
            }
            break;
        case i_stmt::VT_FLOAT:
            {
                float_ptr = &float_v;
            }
            break;
        case i_stmt::VT_BOOL:
            {
                bool_ptr = &bool_v;
            }
            break;
        case i_stmt::VT_I64:
            {
                i64_ptr = &i64_v;
            }
            break;
        case i_stmt::VT_I32:
            {
                i32_ptr = &i32_v;
            }
            break;
        case i_stmt::VT_I16:
            {
                i16_ptr = &i16_v;
            }
            break;
        case i_stmt::VT_I8:
            {
                i8_ptr = &i8_v;
            }
            break;
        case i_stmt::VT_U64:
            {
                u64_ptr = &u64_v;
            }
            break;
        case i_stmt::VT_U32:
            {
                u32_ptr = &u32_v;
            }
            break;
        case i_stmt::VT_U16:
            {
                u16_ptr = &u16_v;
            }
            break;
        case i_stmt::VT_U8:
            {
                u8_ptr = &u8_v;
            }
            break;
        default:
            {
                ret = 1;
            }
            break;
        }

        return ret;
    }

    int odbc_field::set_name( const char * lpszName )
    {
        int ret = 0;
        m_name = lpszName;
        return ret;
    }

    int odbc_field::set_string( const char * lpszName, xos_box::i_string * lpData )
    {
        int ret = 0;
        set_type( i_stmt::VT_CHAR_ARRAY, 0, 0 );
        set_name( lpszName );
        m_pStringA = lpData;
        return ret;
    }

    int odbc_field::set_float_digit_num( int nNum )
    {
        int ret = 0;
        m_nDigitnum = nNum;
        return ret;
    }

    int odbc_field::bind_param( i_stmt * pStmtI )
    {
        int ret = 0;

        odbc_stmt::T * pStmt = (odbc_stmt::T *)pStmtI;

        switch( m_eType )
        {
        case i_stmt::VT_CHAR_ARRAY:
            {
                ret = pStmt->bind_param( m_nIndex, wchar_ptr, 0, &len_or_ptr );
            }
            break;
        case i_stmt::VT_DOUBLE:
            {
                ret = pStmt->bind_param( m_nIndex, double_ptr, m_nDigitnum, &len_or_ptr );
            }
            break;
        case i_stmt::VT_FLOAT:
            {
                ret = pStmt->bind_param( m_nIndex, float_ptr, m_nDigitnum, &len_or_ptr );
            }
            break;
        case i_stmt::VT_BOOL:
            {
                ret = pStmt->bind_param( m_nIndex, bool_ptr, &len_or_ptr );
            }
            break;
        case i_stmt::VT_I64:
            {
                ret = pStmt->bind_param( m_nIndex, i64_ptr, &len_or_ptr );
            }
            break;
        case i_stmt::VT_I32:
            {
                ret = pStmt->bind_param( m_nIndex, i32_ptr, &len_or_ptr );
            }
            break;
        case i_stmt::VT_I16:
            {
                ret = pStmt->bind_param( m_nIndex, i16_ptr, &len_or_ptr );
            }
            break;
        case i_stmt::VT_I8:
            {
                ret = pStmt->bind_param( m_nIndex, i8_ptr, &len_or_ptr );
            }
            break;
        case i_stmt::VT_U64:
            {
                ret = pStmt->bind_param( m_nIndex, u64_ptr, &len_or_ptr );
            }
            break;
        case i_stmt::VT_U32:
            {
                ret = pStmt->bind_param( m_nIndex, u32_ptr, &len_or_ptr );
            }
            break;
        case i_stmt::VT_U16:
            {
                ret = pStmt->bind_param( m_nIndex, u16_ptr, &len_or_ptr );
            }
            break;
        case i_stmt::VT_U8:
            {
                ret = pStmt->bind_param( m_nIndex, u8_ptr, &len_or_ptr );
            }
            break;
        default:
            {
                ret = 1;
            }
            break;
        }

        return ret;
    }

    int odbc_field::bind_col( i_stmt * pStmtI )
    {
        int ret = 0;

        odbc_stmt::T * pStmt = (odbc_stmt::T *)pStmtI;

        switch( m_eType )
        {
        case i_stmt::VT_CHAR_ARRAY:
            {
                ret = pStmt->bind_colum( m_nIndex, wchar_ptr, m_nBufSize, &len_or_ptr );
            }
            break;
        case i_stmt::VT_DOUBLE:
            {
                ret = pStmt->bind_colum( m_nIndex, double_ptr, &len_or_ptr );
            }
            break;
        case i_stmt::VT_FLOAT:
            {
                ret = pStmt->bind_colum( m_nIndex, float_ptr, &len_or_ptr );
            }
            break;
        case i_stmt::VT_BOOL:
            {
                ret = pStmt->bind_colum( m_nIndex, bool_ptr, &len_or_ptr );
            }
            break;
        case i_stmt::VT_I64:
            {
                ret = pStmt->bind_colum( m_nIndex, i64_ptr, &len_or_ptr );
            }
            break;
        case i_stmt::VT_I32:
            {
                ret = pStmt->bind_colum( m_nIndex, i32_ptr, &len_or_ptr );
            }
            break;
        case i_stmt::VT_I16:
            {
                ret = pStmt->bind_colum( m_nIndex, i16_ptr, &len_or_ptr );
            }
            break;
        case i_stmt::VT_I8:
            {
                ret = pStmt->bind_colum( m_nIndex, i8_ptr, &len_or_ptr );
            }
            break;
        case i_stmt::VT_U64:
            {
                ret = pStmt->bind_colum( m_nIndex, u64_ptr, &len_or_ptr );
            }
            break;
        case i_stmt::VT_U32:
            {
                ret = pStmt->bind_colum( m_nIndex, u32_ptr, &len_or_ptr );
            }
            break;
        case i_stmt::VT_U16:
            {
                ret = pStmt->bind_colum( m_nIndex, u16_ptr, &len_or_ptr );
            }
            break;
        case i_stmt::VT_U8:
            {
                ret = pStmt->bind_colum( m_nIndex, u8_ptr, &len_or_ptr );
            }
            break;
        default:
            {
                ret = 1;
            }
            break;
        }

        return ret;
    }

    int odbc_field::get_str_from_buf()
    {
        int ret = 0;
        m_pBuf->set_len( (int)len_or_ptr );
        mgr::container()->misc()->utf16_to_utf8( m_pBuf, m_pStringA );
        return ret;
    }

    int odbc_field::set_str_to_buf()
    {
        int ret = 0;
        mgr::container()->misc()->utf8_to_utf16( m_pStringA, m_pBuf );
        len_or_ptr = m_pBuf->get_len( 0 );
        return ret;
    }

    int odbc_field::clear_value()
    {
        int ret = 0;

        switch( m_eType )
        {
        case i_stmt::VT_CHAR_ARRAY:
            {
                //mgr::container()->crt()->memset( char_ptr, 0, m_nBufSize );
            }
            break;
        case i_stmt::VT_DOUBLE:
            {
                *double_ptr = 0;
            }
            break;
        case i_stmt::VT_FLOAT:
            {
                *float_ptr = 0;
            }
            break;
        case i_stmt::VT_BOOL:
            {
                *bool_ptr = false;
            }
            break;
        case i_stmt::VT_I64:
            {
                *i64_ptr = 0;
            }
            break;
        case i_stmt::VT_I32:
            {
                *i32_ptr = 0;
            }
            break;
        case i_stmt::VT_I16:
            {
                *i16_ptr = 0;
            }
            break;
        case i_stmt::VT_I8:
            {
                *i8_ptr = 0;
            }
            break;
        case i_stmt::VT_U64:
            {
                *u64_ptr = 0;
            }
            break;
        case i_stmt::VT_U32:
            {
                *u32_ptr = 0;
            }
            break;
        case i_stmt::VT_U16:
            {
                *u16_ptr = 0;
            }
            break;
        case i_stmt::VT_U8:
            {
                *u8_ptr = 0;
            }
            break;
        default:
            {
                ret = 1;
            }
            break;
        }

        len_or_ptr = 0;

        return ret;
    }

    //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    // protected method

    int odbc_field::init_data()
    {
        int ret = 0;

        m_eType = i_stmt::VT_I32;
        m_name = "";
        m_nDigitnum = 4;
        m_nBufSize = 0;
        m_nIndex = -1;

        len_or_ptr = 0;
        m_bIsKey = false;
        m_bDirty = true;

        m_pOwnerStringA = 0;
        m_pStringW = 0;
        m_pStringA = 0;
        m_pBuf = 0;

        i64_ptr = 0;
        i64_v = 0;

        set_type( m_eType, 0, 0 );

        return ret;
    }

    //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    // public method

    int odbc_field::init()
    {
        int ret = 0;
        return ret;
    }

    int odbc_field::term()
    {
        int ret = 0;
        xos_stl::release_interface( m_pOwnerStringA );
        xos_stl::release_interface( m_pStringW );
        xos_stl::release_interface( m_pBuf );
        init_data();
        return ret;
    }

} // xos_odbc
